package com.gugee.tiktok.common.model;


import com.gugee.tiktok.common.model.mysql.Aweme;
import com.gugee.tiktok.common.model.mysql.BloggerMain;

import java.util.List;

public class AwemeScore {
    /*private double AVG_LIKE_ALL = 4545.1061; //全网平均点赞
    private double AVG_COMMENT_ALL = 67.1834;//全网平均评论
    private double AVG_SHARE_ALL = 86.5219;//全网平均分享*/
    private double AVG_LIKE_ALL = 398.5094106922762; //全网平均点赞
    private double AVG_COMMENT_ALL = 18.794965494819685;//全网平均评论
    private double AVG_SHARE_ALL = 14.111083658145416;//全网平均分享


    private double AVG_SCORE = 100 * 0.05; //篇均传播力
    private double FANS_SCORE = 100 * 0.25; //粉丝传播力
    private double RISE_SCORE = 100 * 0.65;//爆款传播力

    /**
     * 播主90天的平均值
     */
    double avgLike;
    double avgComment;
    double avgShare;

    List<Aweme> awemes;

    private BloggerMain bloggerMain;
    private double bloggerScore;


    public AwemeScore(BloggerMain bloggerMain, List<Aweme> awemes){
        this.bloggerMain = bloggerMain;
        this.awemes = awemes;
        this.init();
    }

    public BloggerMain getBloggerMain(){
        return bloggerMain;
    }



    private void init(){
        /**
         * 播主90天的平均值
         */
        avgLike = bloggerMain.getOAvgLikes();
        avgComment = bloggerMain.getOAvgReviews();
        avgShare = bloggerMain.getOAvgShare();

        if (awemes != null && awemes.size() == 1) {
            avgLike = (10000 + awemes.get(0).getODiggCount()) / 2;
            avgComment = (1000 + awemes.get(0).getOCommentCount()) / 2;
            avgShare = (100 + awemes.get(0).getOShareCount()) / 2;
        }else if(awemes == null || awemes.size() == 0){
            bloggerScore = 0.0;
        }

        //计算篇均传播力
        bloggerScore = GetRateScore(avgLike, AVG_LIKE_ALL, avgLike, AVG_SCORE * 0.8, ScoreType.like)
                + GetRateScore(avgComment, AVG_COMMENT_ALL, avgComment, AVG_SCORE * 0.1, ScoreType.comment)
                + GetRateScore(avgShare, AVG_SHARE_ALL, avgShare, AVG_SCORE * 0.1, ScoreType.share);
    }


    public double getAwemeScore(Aweme aweme) {
        //计算篇均传播力
        var score1 = bloggerScore;

        if(score1 == 0){
            return 0.0;
        }

        //计算粉丝传播力
        var score2 = GetFansScore(aweme.getODiggCount(), bloggerMain.getOFollowerCount(), FANS_SCORE);

        //计算音乐传播力
        var score3 = 4.5;

        //计算爆款传播力
        var score4_1 = GetRateScore(aweme.getODiggCount() - avgLike, avgLike, aweme.getODiggCount(), RISE_SCORE * 0.8, ScoreType.like);
        var score4_2 = GetRateScore(aweme.getOCommentCount() - avgComment, avgComment, aweme.getOCommentCount(), RISE_SCORE * 0.1, ScoreType.comment);
        var score4_3 = GetRateScore(aweme.getOShareCount() - avgShare, avgShare, aweme.getOShareCount(), RISE_SCORE * 0.1, ScoreType.share);
        var score4 = score4_1 + score4_2 + score4_3;

        var raw_score = score1 + score2 + score3 + score4 < 0 ? 0 : (score1 + score2 + score3 + score4 > 100 ? 100 : score1 + score2 + score3 + score4);

        //确保视频点赞大于500万热度值不低于80，视频点赞大于1000万热度值不低于90
        var bottom_score = 0.0;
        if (aweme.getODiggCount() >= 500 * 10000 && aweme.getODiggCount() <= 1000 * 10000) {
            bottom_score = 80 + ((aweme.getODiggCount() - 500 * 10000) * (10.0 / 500 / 10000));
        }
        if (aweme.getODiggCount() > 1000 * 10000) {
            bottom_score = 90 + Math.log10(aweme.getODiggCount() - 1000 * 10000) / 4;
        }
        var fin_score = raw_score < bottom_score ? bottom_score : raw_score;

        if (Double.isNaN(fin_score)) {
            fin_score = 0;
        }

        if (fin_score == 0) {
            fin_score = 0.1; //最低保底分
        }

        return fin_score;
    }


    private double GetRateScore(double d1, double d2, double d3, double score, ScoreType type) {
        if (d1 < 0) {
            return 0;
        }


        var difficult = GetDifficult(d1, type);
        var difficult2 = GetDifficult(d3, type);
        var rate = d1 / d2 * difficult;
        if (type == ScoreType.like) {
            if (rate > 1) {
                var scale = Math.log(rate) / Math.log(50 * difficult);
                scale = scale > 1 ? 1 : scale;
                return score * 0.6 * scale + score * 0.4 * difficult2;
            } else {
                return score * 0.1 * rate + score * 0.4 * difficult2;
            }
        }
        if (type == ScoreType.comment) {
            if (rate > 1) {
                var scale = Math.log(rate) / Math.log(5 * difficult);
                scale = scale > 1 ? 1 : scale;
                return score * 0.6 * scale + score * 0.4 * difficult2;
            } else {
                return score * 0.1 * rate + score * 0.4 * difficult2;
            }
        }
        if (type == ScoreType.share) {
            if (rate > 1) {
                var scale = Math.log(rate) / Math.log(5 * difficult);
                scale = scale > 1 ? 1 : scale;
                return score * 0.6 * scale + score * 0.4 * difficult2;
            } else {
                return score * 0.1 * rate + score * 0.4 * difficult2;
            }
        }
        return score;
    }


    private double GetFansScore(double likes, double fans, double score) {
        if (likes == 0) {
            return 0;
        }
        //Math.Log(d1 / d2) / Math.Log(100) > 1 ? score : Math.Log(d1 / d2) / Math.Log(100) * score;
        var difficult = GetDifficult(likes + 1, ScoreType.like);
        var difficult2 = Math.log(fans + 1) / Math.log(300000) > 1 ? 1 : Math.log(fans + 1) / Math.log(300000);

        var scaleLikes = fans * 1.0 / 100;
        var rate = (likes + 1) / scaleLikes * difficult;

        var scale = Math.log(rate) / Math.log(50 * difficult);
        scale = scale > 1 ? 1 : scale;
        return score * 0.6 * scale + score * 0.4 * difficult2;

    }

    private double GetDifficult(double d, ScoreType type) {
        if (type == ScoreType.like) {
            return Math.log(d + 1) / Math.log(500000) > 1 ? 1 : Math.log(d + 1) / Math.log(500000);
        }
        if (type == ScoreType.comment) {
            return Math.log(d + 1) / Math.log(10000) > 1 ? 1 : Math.log(d + 1) / Math.log(10000);
        }
        if (type == ScoreType.share) {
            return Math.log(d + 1) / Math.log(10000) > 1 ? 1 : Math.log(d + 1) / Math.log(10000);
        }
        return 1d;
    }

    private enum ScoreType {
        like,
        comment,
        share
    }
}
